
#include "hal.h"
#include "hal_adc.h"

typedef struct
{
	en_adc_samp_ch_sel_t channel;
	en_gpio_port_t port;
	en_gpio_pin_t pin;
}   HAL_ADC_PORT;

static const HAL_ADC_PORT hal_adc_ports[] = 
{
    {AdcExInputCH0, GpioPortA, GpioPin0},
    {AdcExInputCH1, GpioPortA, GpioPin1},
    {AdcExInputCH2, GpioPortA, GpioPin2},
    {AdcExInputCH3, GpioPortA, GpioPin3},
};

void hal_adc_init(HAL_ADC_PARAM *param)
{
    stc_adc_cfg_t	stcAdcCfg;
    DDL_ZERO_STRUCT(stcAdcCfg); 
    ///< 开启ADC/BGR 外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE); 
    Bgr_BgrEnable();        ///< 开启BGR
    ///< ADC 初始化配置
    stcAdcCfg.enAdcMode         = param->mode;               ///<采样模式-单次
    stcAdcCfg.enAdcClkDiv       = AdcMskClkDiv1;            ///<采样分频-1
    stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle12Clk;     ///<采样周期数-12
    stcAdcCfg.enAdcRefVolSel    = param->ref;  							///<参考电压选择-AVDD
    stcAdcCfg.enAdcOpBuf        = param->op_buffer;         ///<OP BUF配置-OPEN
    stcAdcCfg.enInRef           = AdcMskInRefEnable;        ///<内部参考电压使能-开
    stcAdcCfg.enAdcAlign        = AdcAlignRight;            ///<转换结果对齐方式-右
    Adc_Init(&stcAdcCfg);
}

void hal_adc_init_port(en_adc_samp_ch_sel_t channel)
{
    int  i = 0;
    ///< 开启 GPIO外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
    for(i = 0; i<sizeof(hal_adc_ports)/sizeof(HAL_ADC_PORT); i++)
    {
        if(hal_adc_ports[i].channel == channel)
        {
            Gpio_SetAnalogMode(hal_adc_ports[i].port, hal_adc_ports[i].pin); 
            break;
        }
    }
}

void hal_adc_select_channel(en_adc_samp_ch_sel_t channel)
{
    M0P_ADC->CR0_f.SGLMUX = channel; 
}

uint32_t hal_adc_get_result(void)
{
    return M0P_ADC->RESULT;
}

uint32_t hal_wait_result(void)
{
    while(M0P_ADC->SGLSTART);
    return M0P_ADC->RESULT;
}

uint32_t hal_get_single_result(en_adc_samp_ch_sel_t channel)
{
    M0P_ADC->CR0_f.SGLMUX = channel;
    nop(); nop();
    M0P_ADC->SGLSTART = 1u;
    while(M0P_ADC->SGLSTART);
    return M0P_ADC->RESULT;
}
void hal_adc_start(void)
{
    M0P_ADC->SGLSTART = 1u;
}

void hal_adc_stop(void)
{
    M0P_ADC->SGLSTART = 0u;
}